home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / OldSrc / CH4 / SRC / COMPOSE3.FRM (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1997-01-03  |  15.7 KB  |  477 lines

  1. VERSION 4.00
  2. Begin VB.Form CompositeForm3 
  3.    Caption         =   "Composite3"
  4.    ClientHeight    =   5895
  5.    ClientLeft      =   1215
  6.    ClientTop       =   585
  7.    ClientWidth     =   6510
  8.    Height          =   6300
  9.    Left            =   1155
  10.    LinkTopic       =   "Form1"
  11.    ScaleHeight     =   393
  12.    ScaleMode       =   3  'Pixel
  13.    ScaleWidth      =   434
  14.    Top             =   240
  15.    Width           =   6630
  16.    Begin VB.PictureBox MaskPict 
  17.       AutoRedraw      =   -1  'True
  18.       AutoSize        =   -1  'True
  19.       Height          =   75
  20.       Left            =   6120
  21.       Picture         =   "COMPOSE3.frx":0000
  22.       ScaleHeight     =   1
  23.       ScaleMode       =   3  'Pixel
  24.       ScaleWidth      =   1
  25.       TabIndex        =   5
  26.       Top             =   480
  27.       Visible         =   0   'False
  28.       Width           =   75
  29.    End
  30.    Begin VB.PictureBox SourcePict 
  31.       AutoRedraw      =   -1  'True
  32.       AutoSize        =   -1  'True
  33.       Height          =   75
  34.       Left            =   6120
  35.       Picture         =   "COMPOSE3.frx":0446
  36.       ScaleHeight     =   1
  37.       ScaleMode       =   3  'Pixel
  38.       ScaleWidth      =   1
  39.       TabIndex        =   4
  40.       Top             =   0
  41.       Visible         =   0   'False
  42.       Width           =   75
  43.    End
  44.    Begin VB.PictureBox DisplaySwin 
  45.       Height          =   5655
  46.       Left            =   0
  47.       ScaleHeight     =   373
  48.       ScaleMode       =   3  'Pixel
  49.       ScaleWidth      =   413
  50.       TabIndex        =   2
  51.       Top             =   0
  52.       Width           =   6255
  53.       Begin VB.PictureBox DisplayPict 
  54.          AutoRedraw      =   -1  'True
  55.          Height          =   5535
  56.          Left            =   0
  57.          Picture         =   "COMPOSE3.frx":088C
  58.          ScaleHeight     =   365
  59.          ScaleMode       =   3  'Pixel
  60.          ScaleWidth      =   405
  61.          TabIndex        =   3
  62.          Top             =   0
  63.          Width           =   6135
  64.       End
  65.    End
  66.    Begin VB.HScrollBar DisplayHBar 
  67.       Enabled         =   0   'False
  68.       Height          =   255
  69.       Left            =   0
  70.       TabIndex        =   1
  71.       Top             =   5640
  72.       Width           =   6285
  73.    End
  74.    Begin VB.VScrollBar DisplayVBar 
  75.       Enabled         =   0   'False
  76.       Height          =   5655
  77.       Left            =   6240
  78.       TabIndex        =   0
  79.       Top             =   0
  80.       Width           =   255
  81.    End
  82. Attribute VB_Name = "CompositeForm3"
  83. Attribute VB_Creatable = False
  84. Attribute VB_Exposed = False
  85. Option Explicit
  86. Dim SysPalSize As Integer
  87. Dim NumStaticColors As Integer
  88. Dim StaticColor1 As Integer
  89. Dim StaticColor2 As Integer
  90. Dim bytes_source() As Byte
  91. Dim bytes_mask() As Byte
  92. Dim wid(0 To 1) As Long
  93. Dim hgt(0 To 1) As Long
  94. Dim palentry(0 To 255) As PALETTEENTRY
  95. ' ************************************************
  96. ' Create and display the composite image.
  97. ' ************************************************
  98. Public Sub MakeComposite()
  99. Dim bound As Integer
  100. Dim mid_weight As Integer
  101. Dim x As Integer
  102. Dim y As Integer
  103. Dim black As Integer
  104. Dim white As Integer
  105. Dim status As Long
  106. Dim i As Integer
  107. Dim j As Integer
  108. Dim kernel() As Single
  109. Dim wgt As Single
  110. Dim bytes_mask2() As Byte
  111. Dim bytes_source2() As Byte
  112. Dim bytes_source3() As Byte
  113. Dim bytes_dest() As Byte
  114. Dim r1 As Integer
  115. Dim r2 As Integer
  116. Dim dest_factor As Single
  117.     WaitStart
  118.     SourcePict.Visible = False
  119.     MaskPict.Visible = False
  120.     ' Show the user what's going on.
  121.     DisplayPict.Move 0, 0, MaskPict.Width, MaskPict.Height
  122.     DoEvents
  123.     status = SetBitmapBits(DisplayPict.Image, wid(1) * hgt(1), bytes_mask(1, 1))
  124.     DisplayPict.Refresh
  125.     ' Step 1: Low pass filter the mask.
  126.     ' Create a 5x5 low pass kernel.
  127.     bound = 2
  128.     mid_weight = 1
  129.     ReDim kernel(-bound To bound, -bound To bound)
  130.     For i = -bound To bound
  131.         For j = -bound To bound
  132.             kernel(i, j) = 1
  133.         Next j
  134.     Next i
  135.     kernel(0, 0) = mid_weight
  136.     wgt = (2 * bound + 1) * (2 * bound + 1) - 1 + mid_weight
  137.     ' Apply the filter to the mask.
  138.     ReDim bytes_mask2(1 To wid(1), 1 To hgt(1))
  139.     For y = bound + 1 To hgt(1) - bound
  140.         For x = bound + 1 To wid(1) - bound
  141.             r1 = 0
  142.             For i = -bound To bound
  143.                 For j = -bound To bound
  144.                     r1 = r1 + kernel(i, j) * palentry(bytes_mask(x + i, y + j)).peRed
  145.                 Next j
  146.             Next i
  147.             r1 = r1 / wgt
  148.             bytes_mask2(x, y) = NearestNonstaticGray(r1)
  149.         Next x
  150.     Next y
  151.     ' Blank the edges of the mask.
  152.     For y = 1 To hgt(1)
  153.         For x = 1 To bound
  154.             bytes_mask2(x, y) = white
  155.             bytes_mask2(wid(1) - x + 1, y) = white
  156.         Next x
  157.     Next y
  158.     For x = 1 To wid(1)
  159.         For y = 1 To bound
  160.             bytes_mask2(x, y) = white
  161.             bytes_mask2(x, hgt(1) - y + 1) = white
  162.         Next y
  163.     Next x
  164.     ' Show the user what's going on.
  165.     status = SetBitmapBits(DisplayPict.Image, wid(1) * hgt(1), bytes_mask2(1, 1))
  166.     DisplayPict.Refresh
  167.     ' Copy the original image.
  168.     ReDim bytes_source2(1 To wid(0), 1 To hgt(0))
  169.     For x = 1 To wid(0)
  170.         For y = 1 To hgt(0)
  171.             bytes_source2(x, y) = bytes_source(x, y)
  172.         Next y
  173.     Next x
  174.         
  175.     ' Low pass filter the copy.
  176.     ' (Reuse the same 5x5 low pass filter.)
  177.     ' Apply the filter to the copy.
  178.     ReDim bytes_source3(1 To wid(0), 1 To hgt(0))
  179.     For y = bound + 1 To hgt(0) - bound
  180.         For x = bound + 1 To wid(0) - bound
  181.             r1 = 0
  182.             For i = -bound To bound
  183.                 For j = -bound To bound
  184.                     r1 = r1 + kernel(i, j) * palentry(bytes_source2(x + i, y + j)).peRed
  185.                 Next j
  186.             Next i
  187.             r1 = r1 / wgt
  188.             bytes_source3(x, y) = NearestNonstaticGray(r1)
  189.         Next x
  190.     Next y
  191.     ' Show the user what's going on.
  192.     status = SetBitmapBits(DisplayPict.Image, wid(0) * hgt(0), bytes_source3(1, 1))
  193.     DisplayPict.Refresh
  194.     ' Take a weighted average of the original
  195.     ' image and the low pass filtered version
  196.     ' using the filtered mask.
  197.     ReDim bytes_dest(1 To wid(0), 1 To hgt(0))
  198.     For y = 1 To hgt(0)
  199.         For x = 1 To wid(0)
  200.             dest_factor = palentry(bytes_mask2(x, y)).peRed / 255#
  201.             r1 = palentry(bytes_source(x, y)).peRed
  202.             r2 = palentry(bytes_source3(x, y)).peRed
  203.             bytes_dest(x, y) = NearestNonstaticGray((1 - dest_factor) * r1 + dest_factor * r2)
  204.         Next x
  205.     Next y
  206.     ' Display the result.
  207.     status = SetBitmapBits(DisplayPict.Image, wid(0) * hgt(0), bytes_dest(1, 1))
  208.     DisplayPict.Refresh
  209.     DisplayPict.Picture = DisplayPict.Image
  210.     ResetScrollBars
  211.     WaitEnd
  212.     ' This will definitely take a long time so
  213.     ' wake the user.
  214.     Beep
  215. End Sub
  216. ' ************************************************
  217. ' Return the index of the nonstatic gray closest
  218. ' to the given value (assuming the non-static
  219. ' colors are a gray scale created by
  220. ' MatchGrayPalette).
  221. ' ************************************************
  222. Function NearestNonstaticGray(c As Integer) As Integer
  223. Dim dgray As Single
  224.     If c < 0 Then
  225.         c = 0
  226.     ElseIf c > 255 Then
  227.         c = 255
  228.     End If
  229.     dgray = 255 / (StaticColor2 - StaticColor1 - 2)
  230.     NearestNonstaticGray = c / dgray + StaticColor1 + 1
  231. End Function
  232. ' ***********************************************
  233. ' Load the indicated file and prepare to work
  234. ' with its palette.
  235. ' ***********************************************
  236. Public Sub LoadFiles(source_name As String, mask_name As String)
  237. Dim fname As String
  238. Dim i As Integer
  239.     WaitStart
  240.     ' Create DisplayPict's palette.
  241.     MatchGrayPalette 0, DisplayPict, bytes_source
  242.     DoEvents    ' Don't be a total CPU hog.
  243.     ' Load the source file.
  244.     fname = source_name
  245.     SourcePict.Move 0, 0
  246.     SourcePict.Visible = True
  247.     On Error GoTo LoadFileError
  248.     SourcePict.Picture = LoadPicture(fname)
  249.     On Error GoTo 0
  250.     MatchGrayPalette 0, SourcePict, bytes_source
  251.     DoEvents    ' Don't be a total CPU hog.
  252.     ' Load the mask.
  253.     fname = mask_name
  254.     MaskPict.Move 0, 0
  255.     MaskPict.Visible = True
  256.     On Error GoTo LoadFileError
  257.     MaskPict.Picture = LoadPicture(fname)
  258.     On Error GoTo 0
  259.     MatchGrayPalette 1, MaskPict, bytes_mask
  260.     DoEvents    ' Don't be a total CPU hog.
  261.     ' Rerealize each palette.
  262.     SourcePict.ZOrder
  263.     DoEvents
  264.     MaskPict.ZOrder
  265.     DoEvents
  266.     WaitEnd
  267.     Exit Sub
  268. LoadFileError:
  269.     Beep
  270.     MsgBox "Error loading file " & fname & "." & _
  271.         vbCrLf & Error$
  272.     WaitEnd
  273.     Exit Sub
  274. End Sub
  275. ' ***********************************************
  276. ' Load the control's palette so the non-static
  277. ' colors are grays. Map the logical palette to
  278. ' match the system palette. Convert the image to
  279. ' use the non-static grays.
  280. ' Set the following module global variables.
  281. '   palentry()  Image logical palette entries.
  282. '   wid         Width of image.
  283. '   hgt         Height of image.
  284. '   bytes(1 To wid, 1 To hgt)
  285. '               Image pixel values.
  286. ' ***********************************************
  287. Sub MatchGrayPalette(Index As Integer, pic As Control, bytes() As Byte)
  288. Dim logpal As Integer
  289. Dim sys(0 To 255) As PALETTEENTRY
  290. Dim i As Integer
  291. Dim bm As BITMAP
  292. Dim hbm As Integer
  293. Dim status As Long
  294. Dim x As Integer
  295. Dim y As Integer
  296. Dim gray As Single
  297. Dim dgray As Single
  298. Dim c As Integer
  299. Dim clr As Integer
  300.     ' Make sure pic has the foreground palette.
  301.     pic.ZOrder
  302.     i = RealizePalette(pic.hdc)
  303.     DoEvents
  304.     ' Get the system palette entries.
  305.     i = GetSystemPaletteEntries(pic.hdc, 0, SysPalSize, sys(0))
  306.         
  307.     ' Get the image pixels.
  308.     hbm = pic.Image
  309.     status = GetObject(hbm, BITMAP_SIZE, bm)
  310.     wid(Index) = bm.bmWidthBytes
  311.     hgt(Index) = bm.bmHeight
  312.     ReDim bytes(1 To wid(Index), 1 To hgt(Index))
  313.     status = GetBitmapBits(hbm, wid(Index) * hgt(Index), bytes(1, 1))
  314.     ' Make the logical palette as big as possible.
  315.     logpal = pic.Picture.hPal
  316.     If ResizePalette(logpal, SysPalSize) = 0 Then
  317.         Beep
  318.         MsgBox "Error resizing logical palette.", _
  319.             vbExclamation
  320.         Exit Sub
  321.     End If
  322.     ' Blank the non-static colors.
  323.     For i = 0 To StaticColor1
  324.         palentry(i) = sys(i)
  325.     Next i
  326.     For i = StaticColor1 + 1 To StaticColor2 - 1
  327.         With palentry(i)
  328.             .peRed = 0
  329.             .peGreen = 0
  330.             .peBlue = 0
  331.             .peFlags = PC_NOCOLLAPSE
  332.         End With
  333.     Next i
  334.     For i = StaticColor2 To 255
  335.         palentry(i) = sys(i)
  336.     Next i
  337.     i = SetPaletteEntries(logpal, 0, SysPalSize, palentry(0))
  338.     ' Insert the non-static grays.
  339.     gray = 0
  340.     dgray = 255 / (StaticColor2 - StaticColor1 - 2)
  341.     For i = StaticColor1 + 1 To StaticColor2 - 1
  342.         c = gray
  343.         gray = gray + dgray
  344.         With palentry(i)
  345.             .peRed = c
  346.             .peGreen = c
  347.             .peBlue = c
  348.         End With
  349.     Next i
  350.     i = SetPaletteEntries(logpal, StaticColor1 + 1, StaticColor2 - StaticColor1 - 1, palentry(StaticColor1 + 1))
  351.     ' Recreate the image using the new colors.
  352.     For y = 1 To hgt(Index)
  353.         For x = 1 To wid(Index)
  354.             clr = bytes(x, y)
  355.             With sys(clr)
  356.                 c = (CInt(.peRed) + .peGreen + .peBlue) / 3
  357.             End With
  358.             bytes(x, y) = NearestNonstaticGray(c)
  359.         Next x
  360.     Next y
  361.     status = SetBitmapBits(hbm, wid(Index) * hgt(Index), bytes(1, 1))
  362.     ' Realize the gray palette.
  363.     i = RealizePalette(pic.hdc)
  364.     pic.Refresh
  365. End Sub
  366. ' ***********************************************
  367. ' Set the Max and LargeChange properties for the
  368. ' image scroll bars.
  369. ' ***********************************************
  370. Sub ResetScrollBars()
  371.     ' DisplayHBar.
  372.     DisplayHBar.Value = 0
  373.     If DisplaySwin.ScaleWidth >= DisplayPict.Width Then
  374.         DisplayHBar.Enabled = False
  375.     Else
  376.         DisplayHBar.Max = DisplayPict.Width - DisplaySwin.ScaleWidth
  377.         DisplayHBar.LargeChange = DisplaySwin.ScaleWidth
  378.         DisplayHBar.Enabled = True
  379.     End If
  380.     ' DisplayVBar.
  381.     DisplayVBar.Value = 0
  382.     If DisplaySwin.ScaleHeight >= DisplayPict.Height Then
  383.         DisplayVBar.Enabled = False
  384.     Else
  385.         DisplayVBar.Max = DisplayPict.Height - DisplaySwin.ScaleHeight
  386.         DisplayVBar.LargeChange = DisplaySwin.ScaleHeight
  387.         DisplayVBar.Enabled = True
  388.     End If
  389. End Sub
  390. ' ***********************************************
  391. ' Give the form and all the picture boxes an
  392. ' hourglass cursor.
  393. ' ***********************************************
  394. Sub WaitStart()
  395.     MousePointer = vbHourglass
  396.     DisplayPict.MousePointer = vbHourglass
  397.     SourcePict.MousePointer = vbHourglass
  398.     MaskPict.MousePointer = vbHourglass
  399.     DoEvents
  400. End Sub
  401. ' ***********************************************
  402. ' Restore the mouse pointers for the form and all
  403. ' the picture boxes.
  404. ' ***********************************************
  405. Sub WaitEnd()
  406.     MousePointer = vbDefault
  407.     DisplayPict.MousePointer = vbDefault
  408.     SourcePict.MousePointer = vbDefault
  409.     MaskPict.MousePointer = vbDefault
  410. End Sub
  411. Private Sub Form_Load()
  412.     ' Make sure the screen supports palettes.
  413.     If Not GetDeviceCaps(hdc, RASTERCAPS) And RC_PALETTE Then
  414.         Beep
  415.         MsgBox "This monitor does not support palettes.", _
  416.             vbCritical
  417.         End
  418.     End If
  419.     ' Get system palette size and # static colors.
  420.     SysPalSize = GetDeviceCaps(hdc, SIZEPALETTE)
  421.     NumStaticColors = GetDeviceCaps(hdc, NUMRESERVED)
  422.     StaticColor1 = NumStaticColors \ 2 - 1
  423.     StaticColor2 = SysPalSize - NumStaticColors \ 2
  424.     ' Remove the borders from DisplayPict.
  425.     DisplayPict.BorderStyle = vbTransparent
  426.     SourcePict.BorderStyle = vbTransparent
  427.     MaskPict.BorderStyle = vbTransparent
  428. End Sub
  429. ' ***********************************************
  430. ' Make the picture as large as possible.
  431. ' ***********************************************
  432. Private Sub Form_Resize()
  433. Dim hgt As Single
  434. Dim wid As Single
  435.     If WindowState = vbMinimized Then Exit Sub
  436.         
  437.     hgt = ScaleHeight - DisplayHBar.Height - 1
  438.     wid = ScaleWidth - DisplayVBar.Width - 1
  439.     ' Place the controls.
  440.     DisplaySwin.Move 0, 0, wid, hgt
  441.     DisplayVBar.Move _
  442.         DisplaySwin.Left + DisplaySwin.Width + 1, _
  443.         0, DisplayVBar.Width, hgt
  444.     DisplayHBar.Move _
  445.         DisplaySwin.Left, DisplaySwin.Height + 1, _
  446.         wid
  447.     ' Set the scroll bar limits.
  448.     ResetScrollBars
  449. End Sub
  450. ' ***********************************************
  451. ' Move DisplayPict within DisplaySwin.
  452. ' ***********************************************
  453. Private Sub DisplayHBar_Change()
  454.     DisplayPict.Left = -DisplayHBar.Value
  455. End Sub
  456. ' ***********************************************
  457. ' Move DisplayPict within DisplaySwin.
  458. ' ***********************************************
  459. Private Sub DisplayHBar_Scroll()
  460.     DisplayPict.Left = -DisplayHBar.Value
  461. End Sub
  462. ' ***********************************************
  463. ' Move DisplayPict within DisplaySwin.
  464. ' ***********************************************
  465. Private Sub DisplayVBar_Change()
  466.     DisplayPict.Top = -DisplayVBar.Value
  467. End Sub
  468. ' ***********************************************
  469. ' Move DisplayPict within DisplaySwin.
  470. ' ***********************************************
  471. Private Sub DisplayVBar_Scroll()
  472.     DisplayPict.Top = -DisplayVBar.Value
  473. End Sub
  474. Private Sub Form_Unload(Cancel As Integer)
  475.     End
  476. End Sub
  477.